package com.luhongda.music.api.migu;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.luhongda.music.entity.Album;
import com.luhongda.music.entity.Playlist;
import com.luhongda.music.entity.PlaylistDetail;
import com.luhongda.music.entity.Song;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.net.URLDecoder;
import java.util.List;
import java.util.Map;

@Slf4j
public class MiguMusicApi {

    /**
     * 获取推荐歌单
     * pageNo: 默认 1
     * type: 1: 推荐, 2: 最新，默认推荐
     * 一页显示10条。
     */
    public static List<Playlist> recommendPlaylist(Integer page, Integer type) {
        if (page == null) {
            page = 1;
        }
        if (type == null) {
            type = 1;
        }
        String api = "http://api.migu.jsososo.com/recommend/playlist?page=" + page + "&type=" + type;
        String response = HttpUtil.get(api);
        log.info("获取推荐歌单:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        JSONObject data = object.getJSONObject("data");
        JSONArray list = data.getJSONArray("list");
        return JSONUtil.toList(list, Playlist.class);
    }

    /**
     * 获取歌单详情
     */
    public static PlaylistDetail playlistInfo(String id) {
        String api = "http://api.migu.jsososo.com/playlist?id=" + id;
        String response = HttpUtil.get(api);
        log.info("获取歌单信息:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        return JSONUtil.toBean(object.getJSONObject("data"), PlaylistDetail.class);
    }

    /**
     * 获取新歌列表
     * pageNo: 默认 1
     * pageSize: 默认 10
     */
    public static List<Song> newSongs(Integer pageNo, Integer pageSize) {
        if (pageNo == null) {
            pageNo = 1;
        }
        if (pageSize == null) {
            pageNo = 10;
        }
        String api = "http://api.migu.jsososo.com/new/songs?pageNo=" + pageNo + "&pageSize=" + pageSize;
        String response = HttpUtil.get(api);
        JSONObject object = JSONUtil.parseObj(response);
        return JSONUtil.toList(object.getJSONObject("data").getJSONArray("list"), Song.class);
    }

    /**
     * 获取新专辑
     */
    public static List<Album> newAlbums(Integer pageNo, Integer pageSize) {
        if (pageNo == null) {
            pageNo = 1;
        }
        if (pageSize == null) {
            pageNo = 10;
        }
        String api = "http://api.migu.jsososo.com/new/albums?pageNo=" + pageNo + "&pageSize=" + pageSize;
        String response = HttpUtil.get(api);
        JSONObject object = JSONUtil.parseObj(response);
        log.info("获取新专辑:{}", response);
        return JSONUtil.toList(object.getJSONObject("data").getJSONArray("list"), Album.class);
    }

    /**
     * 获取专辑歌曲列表
     */
    public static List<Song> albumsSongs(String id) {
        String api = "http://api.migu.jsososo.com/album/songs?id=" + id;
        String response = HttpUtil.get(api);
        log.info("获取专辑歌曲列表:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        return JSONUtil.toList(object.getJSONArray("data"), Song.class);
    }

    /**
     * 获取音乐下载url
     * id: 歌曲 id 必填
     * type: 128, 320, flac, 返回歌曲链接的码率 默认 128，
     * isRedirect: 默认 0, 非 0 时为重定向至播放链接
     */
    public static String downloadUrl(String id, String type) {
        String api = "http://api.migu.jsososo.com/song/url?id=" + id + "&type=" + type;
        String response = HttpUtil.get(api);
        log.info("获取音乐下载url:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        return (String) object.get("data");
    }

    /**
     * 获取各种下载链接
     *
     * @param id String
     * @return Map
     */
    public static Map<Object, Object> musicDownList(String id) {
        return MapUtil.builder().put("downUrlFlac", downloadUrl(id, "flac")).put("downUrl128", downloadUrl(id, "128")).put("downUrl320", downloadUrl(id, "320")).build();
    }

    public static String getDownloadUrl(String id) {
        Map<Object, Object> musicDownList = musicDownList(id);
        if (musicDownList.get("downUrlFlac") != null) {
            return (String) musicDownList.get("downUrlFlac");
        }
        if (musicDownList.get("downUrl320") != null) {
            return (String) musicDownList.get("downUrl320");
        }
        if (musicDownList.get("downUrl128") != null) {
            return (String) musicDownList.get("downUrl128");
        }
        return null;
    }

    public static String decode(String url) {
        try {
            return URLDecoder.decode(url, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }

    public static void downLoad(String fileUrl, String fileDir, String name) {
        try {
            long beginTime = System.currentTimeMillis();
            String oldFileName = getMusicUrlFileName(fileUrl, false);
            String fileName = StringUtils.isEmpty(name) ? getMusicUrlFileName(fileUrl, true) : name + (fileUrl.contains("flac") ? ".flac" : ".mp3");
            long size = HttpUtil.downloadFile(fileUrl, FileUtil.file(fileDir), new StreamProgress() {
                @Override
                public void start() {
                    log.info("开始下载:{}", fileName);
                }

                @Override
                public void progress(long progressSize) {
                    //log.info("已下载：{}", FileUtil.readableFileSize(progressSize));
                }

                @Override
                public void finish() {
                    log.info("下载完成，耗时:{}", (System.currentTimeMillis() - beginTime) / 1000.0 + "秒。");
                    log.info("正在重命名文件:{}", oldFileName);
                }
            });
            FileUtil.rename(FileUtil.file(fileDir + oldFileName), fileName, true);
            log.info("重命名文件成功,{}  ->->->->->->  {}", oldFileName, fileName);
        } catch (Exception e) {
            log.error("文件:{}，下载失败，url:{}", name, fileUrl);
        }
    }

    public static String getMusicUrlFileName(String url, boolean decode) {
        if (decode) {
            url = decode(url);
        }
        if (url.contains(".mp3?")) {
            String[] arr = url.split(".mp3?");
            String pre = arr[arr.length - 2];
            String[] preArr = pre.split("/");
            return preArr[preArr.length - 1] + ".mp3";
        }
        if (url.contains(".flac?")) {
            String[] arr = url.split(".flac?");
            String pre = arr[arr.length - 2];
            String[] preArr = pre.split("/");
            return preArr[preArr.length - 1] + ".flac";
        }
        throw new RuntimeException("解析url文件名出错:" + url);
    }

    /**
     * 获取专辑歌曲详情
     */
    public static Song songDetail(String id) {
        String api = "http://api.migu.jsososo.com/song?id=" + id;
        String response = HttpUtil.get(api);
        log.info("获取专辑歌曲详情:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        return JSONUtil.toBean(object.getJSONObject("data"), Song.class);
    }

    /**
     * 获取歌词
     */
    public static String lyric(String cid) {
        String response = HttpUtil.get("http://api.migu.jsososo.com/lyric?cid=" + cid);
        JSONObject object = JSONUtil.parseObj(response);
        return (String) object.get("data");
    }


    /**
     * 获取专辑详情
     */
    public static Album albumsDetail(String id) {
        String api = "http://api.migu.jsososo.com/album?id=" + id;
        String response = HttpUtil.get(api);
        log.info("获取专辑歌曲:{}", response);
        JSONObject object = JSONUtil.parseObj(response);
        return JSONUtil.toBean(object.getJSONObject("data"), Album.class);
    }

    /**
     * 搜索
     * keyword: 搜索关键词 必填
     * type: 默认 song，支持：song, playlist, mv, singer, album, lyric
     * pageNo: 默认 1
     */
    public static void search(String keyword, String type, Integer pageNo) {
        if (pageNo == null) {
            pageNo = 1;
        }
        if (StringUtils.isEmpty(type)) {
            type = "song";
        }
        String api = "http://api.migu.jsososo.com/search?keyword=" + keyword + "&type=" + type + "&pageNo=" + pageNo;
        String response = HttpUtil.get(api);
        log.info("获取专辑歌曲:{}", response);
    }

    public static void main(String[] args) {
        //System.out.println(playlists);
        //PlaylistDetail playlistDetail = playlistInfo("115481041");
        //System.out.println(playlistDetail);
        //List<Song> newSongs = newSongs(1, 10);
        //System.out.println(newSongs);
        //List<Album> albums = newAlbums(1, 10);
        //System.out.println(albums);
        //List<Song> albumsSongs = albumsSongs("1003767159");
        //System.out.println(albumsSongs);
        //Album album = albumsDetail("1003767159");
        //System.out.println(album);
        //Song song = songDetail("3790007");
        //System.out.println(song);
        //System.out.println(lyric("60054701923"));
        //System.out.println(musicDownList("3790007"));


        List<Song> newSongs = newSongs(2, 20);
        newSongs.forEach(song -> {
            String url = getDownloadUrl(song.getId());
            if (!StringUtils.isEmpty(url)) {
                downLoad(url, "D:/歌曲下载/", song.getName());
            }
        });
    }
}
